92 lines · 2.7 KB
| 1 | --- |
| 2 | import Repo from '../../../../layouts/Repo.astro'; |
| 3 | import { apiGet } from '../../../../lib/api'; |
| 4 | |
| 5 | const { owner, repo, ref: refParam } = Astro.params; |
| 6 | const ref = refParam || 'main'; |
| 7 | const cookie = Astro.request.headers.get('cookie') || ''; |
| 8 | |
| 9 | let commits: any[] = []; |
| 10 | let error = ''; |
| 11 | |
| 12 | try { |
| 13 | const data = await apiGet(`/api/repos/${owner}/${repo}/commits/${ref}`, cookie); |
| 14 | commits = data.commits || []; |
| 15 | } catch (e: any) { |
| 16 | error = e.message; |
| 17 | } |
| 18 | |
| 19 | function parseAuthor(author: string) { |
| 20 | const match = author.match(/^(.+?) <(.+?)> (\d+) ([+-]\d{4})$/); |
| 21 | if (!match) return { name: author, date: '' }; |
| 22 | const timestamp = parseInt(match[3]) * 1000; |
| 23 | const date = new Date(timestamp); |
| 24 | return { |
| 25 | name: match[1], |
| 26 | date: date.toLocaleDateString('en-US', { |
| 27 | year: 'numeric', |
| 28 | month: 'short', |
| 29 | day: 'numeric', |
| 30 | }), |
| 31 | }; |
| 32 | } |
| 33 | --- |
| 34 | |
| 35 | <Repo owner={owner!} repo={repo!} activeTab="commits" ref={ref}> |
| 36 | {error && <div class="flash-error">{error}</div>} |
| 37 | |
| 38 | <h2 style="font-size: 1rem; margin-bottom: 16px; color: var(--text-muted);"> |
| 39 | Commits on <strong style="color: var(--text);">{ref}</strong> |
| 40 | </h2> |
| 41 | |
| 42 | <div class="commit-list"> |
| 43 | {commits.map((commit: any) => { |
| 44 | const { name, date } = parseAuthor(commit.author); |
| 45 | const shortSha = commit.sha.slice(0, 7); |
| 46 | const firstLine = commit.message.split('\n')[0]; |
| 47 | return ( |
| 48 | <div style=" |
| 49 | display: flex; |
| 50 | justify-content: space-between; |
| 51 | align-items: center; |
| 52 | padding: 12px 16px; |
| 53 | border: 1px solid var(--border); |
| 54 | border-bottom: none; |
| 55 | background: var(--bg-secondary); |
| 56 | font-size: 0.875rem; |
| 57 | " class="commit-row"> |
| 58 | <div style="min-width: 0; flex: 1;"> |
| 59 | <div style="font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"> |
| 60 | <a href={`/${owner}/${repo}/commit/${commit.sha}`} style="color: var(--text);"> |
| 61 | {firstLine} |
| 62 | </a> |
| 63 | </div> |
| 64 | <div style="color: var(--text-muted); font-size: 0.8125rem; margin-top: 2px;"> |
| 65 | {name} committed on {date} |
| 66 | </div> |
| 67 | </div> |
| 68 | <div style="flex-shrink: 0; margin-left: 16px;"> |
| 69 | <a |
| 70 | href={`/${owner}/${repo}/commit/${commit.sha}`} |
| 71 | class="btn" |
| 72 | style="font-family: var(--font-mono); font-size: 0.75rem; padding: 2px 10px;" |
| 73 | > |
| 74 | {shortSha} |
| 75 | </a> |
| 76 | </div> |
| 77 | </div> |
| 78 | ); |
| 79 | })} |
| 80 | </div> |
| 81 | </Repo> |
| 82 | |
| 83 | <style> |
| 84 | .commit-row:first-child { |
| 85 | border-radius: var(--radius) var(--radius) 0 0; |
| 86 | } |
| 87 | .commit-row:last-child { |
| 88 | border-bottom: 1px solid var(--border) !important; |
| 89 | border-radius: 0 0 var(--radius) var(--radius); |
| 90 | } |
| 91 | </style> |
| 92 |